package com.gitee.apanlh.util.sys;

import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.SingletonUtils;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.util.List;

/**	
 * 	系统信息
 * 	
 * 	@author Pan
 *
 */
public class SystemInfo {
	
	/** 当前默认地址 */
	static final String USER_DIR 										= System.getProperty("user.dir");
	/** 系统默认编码格式 */
	static final String DEF_ENCODING 									= System.getProperty("sun.jnu.encoding");
	/** 系统管理器 */
	static final String SECURITY_MANAGER 								= System.getProperty("java.security.manager");
	/** 运行时信息 */
	private static RuntimeMXBean runtimeBean 							= ManagementFactory.getRuntimeMXBean();
	/** 操作系统信息 */
	private static OperatingSystemMXBean systemBean 					= ManagementFactory.getOperatingSystemMXBean();
	
	/** 获取进程PID号 */
	private String pid;
	/** 获取主机名 */
	private String pidName;
	/** 获取完整的PID进程信息 <br>PID@用户名 */
	private String getFullPid;
	/**	 获取可用CPU数量 <br>在虚拟机的特定调用过程中，这个值可能会改变。 <br>虚拟机可用的处理器数不可能小于1 */
	private String cpuAvailable;
	/**	 获取CPU负载 */
	private String cpuLoadAverage;
	/** 获取当前操作系统信息 */	
	private String name;
	/** 系统版本 */
	private String version;
	/** 系统架构 */
	private String arch;
	/** 获取默认系统编码格式 */
	private String encoding;
	/** 系统用户信息 */
	private SysUser user;
	/** 系统磁盘信息 */
	private List<SystemDisk> disks;
	
	/**
	 * 	默认构造函数
	 * 	
	 * 	@author Pan
	 */
	public SystemInfo() {
		super();
		this.encoding = DEF_ENCODING; 
	}
	
	/**		
	 * 	获取进程PID号
	 * 
	 * 	@author Pan
	 * 	@return String
	 */
	public String getPid() {
		if (this.pid == null) {
			String fullPid = getFullPid();
			this.pid = fullPid.substring(0, fullPid.indexOf('@'));
		}
		return this.pid;
	}
	
	/**	
	 * 	获取主机名
	 * 
	 * 	@author Pan
	 * 	@return String
	 */
	public String getPidName() {
		if (this.pidName == null) {
			String fullPid = getFullPid();
			this.pidName = fullPid.substring(fullPid.indexOf('@') + 1);
		}
		return pidName;
	}
	
	/**	
	 * 	获取完整的PID进程信息
	 * 	<br>PID@用户名
	 * 
	 * 	@author Pan
	 * 	@return String
	 */
	public String getFullPid() {
		if (this.getFullPid == null) {
			this.getFullPid = runtimeBean.getName();
		}
		return this.getFullPid;
	}
	
	/**	
	 * 	获取当前操作系统信息
	 * 
	 * 	@author Pan
	 * 	@return String
	 */
	public String getName() {
		if (this.name == null) {
			this.name = systemBean.getName();
		}
		return this.name;
	}
	
	/**	
	 * 	获取可用CPU数量
	 * 	<br>在虚拟机的特定调用过程中，这个值可能会改变。
	 * 	<br>虚拟机可用的处理器数不可能小于1
	 * 	
	 * 	@author Pan
	 * 	@return String
	 */
	public String getCpuAvailable() {
		if (this.cpuAvailable == null) {
			this.cpuAvailable = String.valueOf(systemBean.getAvailableProcessors());
		}
		return this.cpuAvailable;
	}
	
	/**	
	 * 	获取CPU负载
	 * 
	 * 	@author Pan
	 * 	@return String
	 */
	public String getCpuLoadAverage() {
		if (this.cpuLoadAverage == null) {
			this.cpuLoadAverage = String.valueOf(systemBean.getSystemLoadAverage());
		}
		return this.cpuLoadAverage;
	}
	
	/**	
	 * 	获取默认系统编码格式
	 * 
	 * 	@author Pan
	 * 	@return String
	 */
	public String getEncoding() {
		return this.encoding;
	}
	
	/**	
	 * 	获取系统用户信息
	 * 	<br> 懒加载
	 * 	
	 * 	@author Pan
	 * 	@return SysUser
	 */
	public SysUser getUser() {
		if (this.user == null) {
			this.user = SingletonUtils.get(SysUser.class);
		}
		return this.user;
	}
	
	/**
	 * 	获取系统磁盘信息
	 * 
	 * 	@author Pan
	 * 	@return List
	 */
	public List<SystemDisk> getDisks() {
		File[] disksFile = SystemDisk.getDisks();
		
		if (this.disks == null) {
			int len = disksFile.length;
			disks = CollUtils.newArrayList(len);
			for (int i = 0; i < len; i++) {
				disks.add(SystemDisk.create(disksFile[i]));
			}
		}
		return this.disks;
	}
	
	@Override
	public String toString() {
		return "SystemInfo [pid=" + pid + ", pidName=" + pidName + ", getFullPid=" + getFullPid + ", cpuAvailable="
				+ cpuAvailable + ", cpuLoadAverage=" + cpuLoadAverage + ", name=" + name + ", version=" + version
				+ ", arch=" + arch + ", encoding=" + encoding + ", user=" + user + ", disks=" + disks + "]";
	}
	
	/**	
	 * 	创建系统信息
	 * 	
	 * 	@author Pan
	 * 	@return SystemInfo
	 */
	public static SystemInfo create() {
		return SingletonUtils.get(SystemInfo.class);
	}
}
